package ru.aptu.snmp_trap.manager;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.CommunityTarget;
import org.snmp4j.MessageDispatcher;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.security.Priv3DES;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.smi.*;
import org.snmp4j.transport.AbstractTransportMapping;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;

public class TrapReceiver implements CommandResponder {
    private static final String CONFIG_FILE = "snmp_manager.properties";

    private Logger logger;

    private OID oid;
    
    private String ip;

    public TrapReceiver() {
        Properties myProps = new Properties();
        FileInputStream MyInputStream = null;
        try {
            MyInputStream = new FileInputStream(CONFIG_FILE);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            myProps.load(MyInputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        oid = new OID(myProps.getProperty("message.oid"));

        logger = LoggerFactory.getLogger(TrapReceiver.class);

        ip = myProps.getProperty("receiver.ip");
    }

    public static void main(String[] args) {
        TrapReceiver snmp4jTrapReceiver = new TrapReceiver();
        try {
            snmp4jTrapReceiver.listen();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public synchronized void listen() throws IOException {
        TransportIpAddress address = new UdpAddress(ip);
        AbstractTransportMapping transport = new DefaultUdpTransportMapping((UdpAddress) address);

        ThreadPool threadPool = ThreadPool.create("DispatcherPool", 10);
        MessageDispatcher messageDispatcher = new MultiThreadedMessageDispatcher(threadPool, new MessageDispatcherImpl());

        messageDispatcher.addMessageProcessingModel(new MPv1());
        messageDispatcher.addMessageProcessingModel(new MPv2c());

        SecurityProtocols.getInstance().addDefaultProtocols();
        SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES());

        CommunityTarget target = new CommunityTarget();
        target.setCommunity(new OctetString("public"));

        Snmp snmp = new Snmp(messageDispatcher, transport);
        snmp.addCommandResponder(this);

        transport.listen();
        System.out.println("Listening on " + address);

        try {
            this.wait();
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        }
    }

    public synchronized void processPdu(CommandResponderEvent cmdRespEvent) {
        PDU pdu = cmdRespEvent.getPDU();
        if (pdu != null) {
            logPdu(pdu);
        }
    }

    private void logPdu(PDU pdu) {
        logger.info(pdu.getVariable(oid).toString());
    }
}

